#pragma once

#include <windows.h>
#include <mmsystem.h>

// -----------------------------------------------------
//  Real Time Loop
// -----------------------------------------------------
// - http://www.angelfire.com/rpg2/vertexnormal/tutorials/loop_tutorial.html

class CRealTimeLoop
{
public:
	///////////////
	// VARIABLES //
	///////////////
	float				frequency;		// Frequency ( Maximum FrameRate Per Second )
	
	DWORD				time0, time1;	// Initial Time, New Time
	float				frameTime;		// Delta Time
	int					numLoops;		// Number Of Loops

	DWORD				TICK_TIME;		// Maximum Amount Of Ticks
	int					MAX_LOOPS;		// Maximum Amount Of Loops

	bool				mNetworkGame;	// Is It A Network Game?

	///////////////
	// FUNCTIONS //
	///////////////

	// Constructor
	CRealTimeLoop					(void);
	CRealTimeLoop					(const float f);
	
	// Destructor
	~CRealTimeLoop					(void);

	// Set Frequency
	void	SetFrequency			(const float f);

	// Set Max Loops
	void	SetMaxLoops				(const int l);

	// Set Network Game
	void	SetNetworkGame			(const bool nG);

	// Get Frame Delta Time ( Time Taken In The Loop )
	float	GetFrameDeltaTime		(void);

	// Get Percent Within Tick ( Render Interpolation ) ( Account For NumLoops Overflow Causing Percent > 1 )
	float	GetPercentWithinTick	(void);

	// Prepare Real-Time Loop, Call This Function Before The While Loop
	inline void UpdatePre(void)
	{
		// Prepare Real-Time Loop
		this->time1		= timeGetTime();
		this->frameTime	= 0.0f;
		this->numLoops	= 0;
	}

	// Real-Time Loop Condition, Call This Function In The While Loop Condition [ while ( CTimeControl::CheckUpdate ) ]
	inline bool UpdateCheck(void)
	{
		if ( time1 - time0 > TICK_TIME && numLoops < MAX_LOOPS )
			return true;

		return false;
	}

	// Update Real-Time Loop, Call This Function In The While Loop
	inline void UpdateLoop(void)
	{
		this->time0		+= TICK_TIME;
		this->frameTime	+= TICK_TIME;
		this->numLoops	++;
	}

	// Discard Pending Time If Playing Solo And Game Logic Takes Way Too Long, Call This Function After The PostUpdate Function Is Called
	inline void UpdatePlayingSoloDiscardPendingTime(void)
	{
		if ( !mNetworkGame && time1 - time0 > TICK_TIME )
			time0 = time1 - TICK_TIME;
	}
};